Reto semana 2 - Matematicas para Machine Learning¶

A. Escribimos el codigo que lee y grafica la imagen en escala de grises¶
In [4]:
!pip3 install opencv-python
Defaulting to user installation because normal site-packages is not writeable
Collecting opencv-python
  Downloading opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_x86_64.whl.metadata (20 kB)
Requirement already satisfied: numpy>=1.21.2 in /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from opencv-python) (2.2.3)
Downloading opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_x86_64.whl (56.7 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.7/56.7 MB 19.0 MB/s eta 0:00:00a 0:00:01
Installing collected packages: opencv-python
Successfully installed opencv-python-4.11.0.86
In [1]:
# Importar librerías
import numpy as np
import cv2
import matplotlib.pyplot as plt
from PIL import Image
import os
In [2]:
# ponemos el path de la imagen guardada en nuestra carpeta
img_path = 'EdificioMarioLaserna.png'
In [3]:
# leemos y mostramos la imagen
img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)

plt.figure(figsize=(10, 6))
plt.imshow(img, cmap='gray')
plt.title("Imagen original en escala de grises")
plt.axis('off')
plt.show()
B. calculamos las matrices usando svd de numpy¶
In [4]:
# Convertir a tipo float para calcular el SVD
A = np.array(img, dtype=float)

U, S, VT = np.linalg.svd(A, full_matrices=False)
C. Reconstruimos la imagen usando los p=10 primeros valores singulares¶
In [5]:
p = 10
Ur = U[:, :p]
Sr = np.diag(S[:p])
VTr = VT[:p, :]

Ar = Ur @ Sr @ VTr

plt.figure(figsize=(10, 6))
plt.imshow(Ar, cmap='gray')
plt.title(f"Reconstrucción con p = {p}")
plt.axis('off')
plt.show()
D. Exploramos con diferentes valores de p¶
In [7]:
def reconstruir_y_graficar(p):
    Ur = U[:, :p]
    Sr = np.diag(S[:p])
    VTr = VT[:p, :]
    Ar = Ur @ Sr @ VTr

    plt.figure(figsize=(10, 6))
    plt.imshow(Ar, cmap='gray')
    plt.title(f"Reconstrucción con p = {p}")
    plt.axis('off')
    plt.show()

    original_size = A.size
    compressed_size = Ur.size + Sr.size + VTr.size
    compression_ratio = 100 * compressed_size / original_size
    print(f"Tamaño original: {original_size} elementos")
    print(f"Tamaño comprimido: {compressed_size} elementos")
    print(f"Nivel de compresión: {compression_ratio:.2f}% del original")

# Ejemplo visual con diferentes valores de p
for p in [5, 10, 20, 50, 75, 100, 200]:
    reconstruir_y_graficar(p)
Tamaño original: 324860 elementos
Tamaño comprimido: 5920 elementos
Nivel de compresión: 1.82% del original
Tamaño original: 324860 elementos
Tamaño comprimido: 11890 elementos
Nivel de compresión: 3.66% del original
Tamaño original: 324860 elementos
Tamaño comprimido: 23980 elementos
Nivel de compresión: 7.38% del original
Tamaño original: 324860 elementos
Tamaño comprimido: 61450 elementos
Nivel de compresión: 18.92% del original
Tamaño original: 324860 elementos
Tamaño comprimido: 94050 elementos
Nivel de compresión: 28.95% del original
Tamaño original: 324860 elementos
Tamaño comprimido: 127900 elementos
Nivel de compresión: 39.37% del original
Tamaño original: 324860 elementos
Tamaño comprimido: 275800 elementos
Nivel de compresión: 84.90% del original

Analisis de p¶

Se planteo primeramente que un p = 50 pasa la prueba visual, pero se ingreso el valor de 75 posteriormente para identificar que en este si ya no hay tantos elementos borrosos en la imagen, los datos especificos del analisis son los siguientes:

Tamaño original: 324860 pixeles

Tamaño comprimido: 94050 pixeles

Nivel de compresión: 28.95% del original